﻿using MailKit.Net.Smtp;
using Microsoft.AspNetCore.Mvc.Rendering;
using MimeKit;
using PlatformNetCore.Common;
using PlatformNetCore.Entity;
using PlatformNetCore.IRepository;
using PlatformNetCore.IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;

namespace PlatformNetCore.Service
{
    public class PortalService : IPortalService
    {
        private readonly IAdRepository adRepository;
        private readonly INewsRepository newsRepository;
        private readonly ISinglePageRepository singlePageRepository;
        private readonly IVideosRepository videosRepository;
        private readonly IImagesRepository imageRepository;
        private readonly ICategoryRepository categoryRepository;
        private readonly ISmtpConfigRepository smtpConfigRepository;
        private readonly ISmtpTemplateRepository smtpTemplateRepository;
        private readonly IJobsRepository jobsRepository;
        private readonly IPartnerRepository partnerRepository;
        private readonly IFAQsRepository fAQsRepository;
        private readonly ISubscribeRepository subscribeRepository;
        public PortalService(INewsRepository _newsRepository, ISinglePageRepository _singlePageRepository, IVideosRepository _videosRepository
            , IImagesRepository _imageRepository, ICategoryRepository _categoryRepository, IJobsRepository _jobsRepository
            , ISmtpConfigRepository _smtpConfigRepository, ISmtpTemplateRepository _smtpTemplateRepository
            , IPartnerRepository _partnerRepository, IAdRepository _adRepository, IFAQsRepository _fAQsRepository
            , ISubscribeRepository _subscribeRepository)
        {
            newsRepository = _newsRepository;
            singlePageRepository = _singlePageRepository;
            videosRepository = _videosRepository;
            imageRepository = _imageRepository;
            categoryRepository = _categoryRepository;
            smtpConfigRepository = _smtpConfigRepository;
            smtpTemplateRepository = _smtpTemplateRepository;
            jobsRepository = _jobsRepository;
            partnerRepository = _partnerRepository;
            adRepository = _adRepository;
            fAQsRepository = _fAQsRepository;
            subscribeRepository = _subscribeRepository;
        }

        #region 后台首页统计
        public AdminInfo GetAdminInfo()
        {
            AdminInfo adminInfo = new AdminInfo()
            {
                DocumentCount = newsRepository.Count(k => k.IsDel == 0 && k.NewsType == NewsType.Literature.ToString()),
                ShareCount = newsRepository.Count(k => k.IsDel == 0 && k.NewsType == NewsType.EmployeeSharing.ToString()),
                AdCount = adRepository.Count(k => k.IsAvailable == 1 && k.IsDel == 0),
                FAQsCount = fAQsRepository.Count(k => k.IsAvailable == 1 && k.IsDel == 0),
                ImagesCount = imageRepository.Count(k => k.IsAvailable == 1 && k.IsDel == 0),
                JobsCount = jobsRepository.Count(k => k.IsDel == 0 && k.IsAvailable == 1),
                PartnerCount = partnerRepository.Count(k => k.IsDel == 0),
                VideosCount = videosRepository.Count(k => k.IsAvailable == 1 && k.IsDel == 0),
                SubscribeCount = subscribeRepository.Count(k => k.IsDel == 0),
                PageCount = singlePageRepository.Count(k => k.IsDel == 0)
            };
            return adminInfo;
        }
        #endregion

        #region 前台
        /// <summary>
        /// 前台首页
        /// </summary>
        /// <returns></returns>
        public HomeInfo GetHomeInfo()
        {
            HomeInfo homeInfo = new HomeInfo();
            homeInfo.SinglePageIndex = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.Index.ToString() && k.IsDel == 0);
            homeInfo.SinglePageJoinUs = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.JoinUs.ToString() && k.IsDel == 0);
            homeInfo.Partners = partnerRepository.GetList(k => k.IsDel == 0).OrderBy(s => s.SortNo).ThenByDescending(m => m.AddDate).ToList();
            homeInfo.Videos = videosRepository.GetList(k => k.IsAvailable == 1 && k.IsDel == 0 && k.VideoType == VideoType.Index.ToString()).OrderBy(s => s.SortNo).ThenByDescending(m => m.AddDate).ToList();
            return homeInfo;
        }
        /// <summary>
        /// 关于我们
        /// </summary>
        /// <returns></returns>
        public AboutInfo GetAboutInfo(string menuCode)
        {
            AboutInfo aboutInfo = new AboutInfo();
            aboutInfo.Ad = adRepository.GetByExpression(k => k.AdSlot != null && k.AdSlot.AdSlotCode == "A001" && k.IsAvailable == 1 && k.IsDel == 0);
            switch (menuCode)
            {
                case "A001":
                    aboutInfo.SinglePage = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.AboutUS.ToString() && k.IsDel == 0);
                    aboutInfo.Video = videosRepository.GetByExpression(k => k.VideoType == VideoType.Introduction.ToString() && k.IsAvailable == 1 && k.IsDel == 0);
                    break;
                case "A002":
                    aboutInfo.Images = imageRepository.GetList(k => k.IsAvailable == 1 && k.IsDel == 0 && k.ImagesType == ImagesType.Qualification.ToString()).OrderBy(s => s.SortNo).ThenByDescending(m => m.AddDate).ToList();
                    break;
                case "A003":
                    aboutInfo.SinglePage = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.BrandAndCulture.ToString() && k.IsDel == 0);
                    break;
            }
            return aboutInfo;
        }
        /// <summary>
        /// 配药安全
        /// </summary>
        /// <returns></returns>
        public SafetyInfo GetSafetyInfo()
        {
            SafetyInfo safetyInfo = new SafetyInfo();
            safetyInfo.Ad = adRepository.GetByExpression(k => k.AdSlot != null && k.AdSlot.AdSlotCode == "A002" && k.IsAvailable == 1 && k.IsDel == 0);
            safetyInfo.SinglePage = singlePageRepository.GetByExpression(k => k.IsDel == 0 && k.SingPageType == SinglePageType.DispensingSafety.ToString());
            safetyInfo.Videos = videosRepository.GetList(k => k.IsAvailable == 1 && k.IsDel == 0 && k.VideoType == VideoType.Dispensing.ToString()).OrderBy(s => s.SortNo).ThenByDescending(m => m.AddDate).ToList();
            return safetyInfo;
        }
        /// <summary>
        /// 产品中心
        /// </summary>
        /// <returns></returns>
        public ProductInfo GetProductInfo(string menuCode)
        {
            ProductInfo productInfo = new ProductInfo();
            productInfo.Ad = adRepository.GetByExpression(k => k.AdSlot != null && k.AdSlot.AdSlotCode == "P001" && k.IsAvailable == 1 && k.IsDel == 0);
            switch (menuCode)
            {
                case "C001":
                    productInfo.SinglePage = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.StaticCenterSupplement.ToString() && k.IsDel == 0);
                    productInfo.Video = videosRepository.GetByExpression(k => k.VideoType == VideoType.Static.ToString() && k.IsAvailable == 1 && k.IsDel == 0);
                    break;
                case "C002":
                    productInfo.SinglePage = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.MinMoveCenter.ToString() && k.IsDel == 0);
                    break;
                case "C003":
                    productInfo.SinglePage = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.NurseSafety.ToString() && k.IsDel == 0);
                    break;
                case "C004":
                    productInfo.SinglePage = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.EfficientConfig.ToString() && k.IsDel == 0);
                    break;
            }
            return productInfo;
        }
        /// <summary>
        /// 数据中心
        /// </summary>
        /// <param name="menuCode"></param>
        /// <returns></returns>
        public DataCenterInfo GetDataCenterInfo(string menuCode, int pageindex = 1, int pagesize = 4)
        {
            DataCenterInfo dataCenterInfo = new DataCenterInfo();
            dataCenterInfo.Ad = adRepository.GetByExpression(k => k.AdSlot != null && k.AdSlot.AdSlotCode == "D001" && k.IsAvailable == 1 && k.IsDel == 0);
            switch (menuCode)
            {
                case "D001":
                    dataCenterInfo.NewsList = newsRepository.GetPagerList(pageindex, pagesize, k => k.NewsType == NewsType.Literature.ToString() && k.IsAvailable == 1 && k.IsDel == 0);
                    break;
                case "D002":
                    dataCenterInfo.SinglePage = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.Branches.ToString() && k.IsDel == 0);
                    dataCenterInfo.Images = imageRepository.GetPagerList(pageindex, pagesize, k => k.ImagesType == ImagesType.TestMachine.ToString() && k.IsDel == 0 && k.IsAvailable == 1);
                    break;
                case "D003":
                    dataCenterInfo.Images = imageRepository.GetPagerList(pageindex, pagesize, k => k.ImagesType == ImagesType.ExpertSupport.ToString() && k.IsDel == 0 && k.IsAvailable == 1);
                    break;
            }
            return dataCenterInfo;
        }
        /// <summary>
        /// 招贤纳士
        /// </summary>
        /// <returns></returns>
        public JobsInfo GetJobsInfo(string menuCode, string jobID = "", string positionID = "", string search = "", int pageindex = 1, int pagesize = 8)
        {
            JobsInfo jobsInfo = new JobsInfo();
            jobsInfo.Ad = adRepository.GetByExpression(k => k.AdSlot != null && k.AdSlot.AdSlotCode == "E001" && k.IsAvailable == 1 && k.IsDel == 0);
            switch (menuCode)
            {
                case "E001":
                    jobsInfo.SinglePage = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.Recruitment.ToString() && k.IsDel == 0);
                    break;
                case "E002":
                    //职能
                    var jobslist = categoryRepository.GetList(k => k.CategoryType == CategoryType.JobsType.ToString() && k.IsAvailable == 1 && k.IsDel == 0);
                    List<SelectListItem> jobsTypeList = jobslist.Select(s => new SelectListItem()
                    {
                        Value = s.ID,
                        Text = s.CategoryName,
                        Selected = s.ID.EqualsIgnoreCase(jobID)
                    }).ToList();
                    jobsTypeList.Insert(0, new SelectListItem() { Text = "全部", Value = string.Empty, Selected = string.IsNullOrWhiteSpace(jobID) });
                    jobsInfo.JobsTypeList = jobsTypeList;
                    //职位
                    var poslist = categoryRepository.GetList(k => k.CategoryType == CategoryType.PositionType.ToString() && k.IsAvailable == 1 && k.IsDel == 0);
                    List<SelectListItem> positionTypeList = poslist.Select(s => new SelectListItem()
                    {
                        Value = s.ID,
                        Text = s.CategoryName,
                        Selected = s.ID.EqualsIgnoreCase(positionID)
                    }).ToList();
                    positionTypeList.Insert(0, new SelectListItem() { Text = "全部", Value = string.Empty, Selected = string.IsNullOrWhiteSpace(positionID) });
                    jobsInfo.PositionTypeList = positionTypeList;

                    Expression<Func<Jobs, bool>> predicate = k => k.IsAvailable == 1 && k.IsDel == 0;
                    if (!string.IsNullOrWhiteSpace(jobID))
                    {
                        predicate = predicate.And(k => k.JobID == jobID);
                    }
                    if (!string.IsNullOrWhiteSpace(positionID))
                    {
                        predicate = predicate.And(k => k.PositionID == positionID);
                    }
                    if (!string.IsNullOrWhiteSpace(search))
                    {
                        predicate = predicate.And(k => k.Title.Contains(search));
                    }
                    jobsInfo.Jobs = jobsRepository.GetPagerList(pageindex, pagesize, predicate);
                    break;
            }
            return jobsInfo;
        }
        /// <summary>
        /// 职位详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public JobsDetail GetJobsDetail(string id)
        {
            JobsDetail jobsDetail = new JobsDetail();
            //广告背景
            jobsDetail.Ad = adRepository.GetByExpression(k => k.AdSlot != null && k.AdSlot.AdSlotCode == "E001" && k.IsAvailable == 1 && k.IsDel == 0);
            //Jobs
            jobsDetail.Jobs = jobsRepository.GetById(id);
            return jobsDetail;
        }
        /// <summary>
        /// 员工分享
        /// </summary>
        /// <param name="menuCode"></param>
        /// <returns></returns>
        public EmployeeInfo GetEmployee(string menuCode,int pageindex = 1,int pagesize = 12)
        {
            EmployeeInfo employeeInfo = new EmployeeInfo();
            employeeInfo.Ad = adRepository.GetByExpression(k => k.AdSlot != null && k.AdSlot.AdSlotCode == "F001" && k.IsAvailable == 1 && k.IsDel == 0);
            switch (menuCode)
            {
                case "F001":
                    employeeInfo.Images = imageRepository.GetPagerList(pageindex,pagesize,k => k.ImagesType == ImagesType.TrainingSystem.ToString() && k.IsDel == 0 && k.IsAvailable == 1);
                    break;
                case "F002":
                    employeeInfo.News = newsRepository.GetPagerList(1, 3, k => k.NewsType == NewsType.EmployeeSharing.ToString() && k.IsAvailable == 1 && k.IsDel == 0);
                    employeeInfo.Images = imageRepository.GetPagerList(pageindex, pagesize, k => k.ImagesType == ImagesType.EmployeeSharing.ToString() && k.IsAvailable == 1 && k.IsDel == 0);
                    break;
            }
            return employeeInfo;
        }
        /// <summary>
        /// 员工分享详情
        /// </summary>
        /// <param name="menuCode"></param>
        /// <param name="id"></param>
        /// <returns></returns>
        public EmployeeDetail GetEmployeeDetail(string id)
        {
            EmployeeDetail employeeDetail = new EmployeeDetail();
            employeeDetail.Ad = adRepository.GetByExpression(k => k.AdSlot != null && k.AdSlot.AdSlotCode == "F001" && k.IsAvailable == 1 && k.IsDel == 0);
            employeeDetail.News = newsRepository.GetById(id);
            return employeeDetail;
        }
        /// <summary>
        /// 客服中心
        /// </summary>
        /// <returns></returns>
        public CustomerInfo GetCustomerInfo(string menuCode)
        {
            CustomerInfo customerInfo = new CustomerInfo();
            customerInfo.Ad = adRepository.GetByExpression(k => k.AdSlot != null && k.AdSlot.AdSlotCode == "G001" && k.IsAvailable == 1 && k.IsDel == 0);
            switch (menuCode)
            {
                case "G001":
                    customerInfo.FAQs = fAQsRepository.GetList(k => k.IsAvailable == 1 && k.IsDel == 0).ToList();
                    break;
                case "G002":
                    customerInfo.SinglePage = singlePageRepository.GetByExpression(k => k.SingPageType == SinglePageType.ContactUS.ToString() && k.IsDel == 0);
                    break;
                case "G003":

                    break;
            }
            return customerInfo;
        }
        /// <summary>
        /// 提交留言
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public ResultResponse SubmitComment(Subscribe model)
        {
            ResultResponse resultResponse = new ResultResponse() { success = false, msg = CommonConst.Fail };
            if (model == null)
            {
                resultResponse.msg = "信息未填写完整";
                return resultResponse;
            }
            if (string.IsNullOrWhiteSpace(model.Title))
            {
                resultResponse.msg = "请填写留言标题";
                return resultResponse;
            }
            if (string.IsNullOrWhiteSpace(model.Content))
            {
                resultResponse.msg = "请填写留言内容";
                return resultResponse;
            }
            if (string.IsNullOrWhiteSpace(model.Person))
            {
                resultResponse.msg = "请填写联系人";
                return resultResponse;
            }
            if (string.IsNullOrWhiteSpace(model.Phone))
            {
                resultResponse.msg = "请填写联系方式";
                return resultResponse;
            }
            model.ID = IdentityCreator.NextIdentity;
            model.AddBy = model.Person;
            model.AddDate = DateTime.Now;
            resultResponse.success = subscribeRepository.Add(model);
            resultResponse.msg = resultResponse.success ? CommonConst.Success : CommonConst.Fail;
            return resultResponse;
        }

        /// <summary>
        /// 发邮件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="senderEmail"></param>
        /// <param name="mailTo"></param>
        /// <param name="mailcc"></param>
        /// <param name="subject"></param>
        /// <param name="body"></param>
        /// <param name="smtpServer"></param>
        /// <param name="fromEmail"></param>
        /// <param name="displayName"></param>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="port"></param>
        /// <param name="enableSsl"></param>
        public ResultResponse SendMail(EmailModel model)
        {
            ResultResponse result = new ResultResponse() { success = false, msg = CommonConst.Fail };
            SmtpConfig config = smtpConfigRepository.FirstOrDefault();
            if (config == null)
            {
                return result;
            }
            SmtpTemplate template = smtpTemplateRepository.GetByExpression(k => k.SmtpCode == "T001");
            if (template == null)
            {
                return result;
            }
            string sender = string.Format("{0}.{1}", model.lastName, model.firstName);
            string senderEmail = config.Account;
            string mailTo = config.Email;
            string mailcc = string.Empty;
            string subject = model.jobtitle;
            string body = template.Content.Replace("{name}", sender).Replace("{company}", model.company).Replace("{email}", model.email)
                .Replace("{phone}", model.phone).Replace("{country}", model.country).Replace("{message}", model.message);
            string smtpServer = config.SmtpHost;
            string fromEmail = config.Account;
            string displayName = model.jobtitle;
            string userName = config.Account;
            string password = config.Pwd;
            int port = config.Port;
            bool enableSsl = config.IsSSL == 1;

            var message = new MimeMessage();
            message.From.Add(new MailboxAddress(displayName, fromEmail));
            message.To.Add(new MailboxAddress("web1", mailTo));

            if (!string.IsNullOrEmpty(mailcc))
                message.Cc.Add(new MailboxAddress("web2", mailcc));

            message.Subject = subject;
            message.Body = new TextPart("html")
            {
                Text = body
            };
            message.ReplyTo.Add(new MailboxAddress(sender, senderEmail));

            using (var client = new SmtpClient())
            {
                client.Connect(smtpServer, port, enableSsl);
                //SMTP server authentication if needed
                client.Authenticate(userName, password);

                client.Send(message);

                client.Disconnect(true);
            }
            result.success = true;
            result.msg = CommonConst.Success;
            return result;
        }
        #endregion

    }
}
